﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace PokemonBattle.PokemonData.Rom
{
    public class ImageService : IDisposable
    {
        private static BinaryFormatter formatter = new BinaryFormatter();
        private FileStream stream;
        private Dictionary<long, WeakReference> dic;

        public long OffSet { get; private set; }

        public void LoadData(string filePath, long offset = 0)
        {
            Dispose();
            stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            dic = new Dictionary<long, WeakReference>();
            this.OffSet = offset;
        }

        public Bitmap GetImage(long position)
        {
            if (position < 0) return null;
            try
            {
                lock (this)
                {
                    var reference = new WeakReference(ReadData(position + this.OffSet, stream));
                    if (!dic.ContainsKey(position))
                    {
                        dic.Add(position, reference);
                    }
                    else if (!dic[position].IsAlive)
                    {
                        dic[position] = reference;
                    }
                    return (Bitmap)dic[position].Target;
                }
            }
            catch (Exception ex)
            {

            }
            return null;
        }

        #region IDisposable

        public void Dispose()
        {
            if (this.stream != null)
            {
                stream.Flush();
                stream.Close();
                stream = null;
            }
            dic = null;
            GC.Collect();
        }

        #endregion

        #region static

        private static object ReadData(long position, FileStream stream)
        {
            try
            {
                stream.Seek(position, SeekOrigin.Begin);
                return formatter.Deserialize(stream);
            }
            catch (Exception ex)
            {
            }
            return null;
        }

        public static long SavaImage(Bitmap image, Stream data)
        {
            if (image == null || data == null)
            {
                return -1L;
            }

            long position = -1L;
            try
            {
                data.Seek(0L, SeekOrigin.End);
                position = data.Position;
                formatter.Serialize(data, image);
            }
            catch (Exception ex)
            {
                position = -1L;
            }
            return position;
        }

        #endregion
    }
}